﻿Imports System
Imports System.Collections
Imports System.Collections.Generic
Imports System.ComponentModel
Imports System.ComponentModel.Design
Imports System.Diagnostics
Imports System.Drawing
Imports System.Drawing.Design
Imports System.Reflection
Imports System.Runtime.CompilerServices
Imports System.Workflow.ComponentModel
Imports System.Workflow.ComponentModel.Compiler
Imports System.Workflow.ComponentModel.Design
Imports System.Workflow.Runtime.DebugEngine

Namespace System.Workflow.Activities
    <SRDescription("ReplicatorActivityDescription"), ToolboxItem(GetType(ActivityToolboxItem)), ToolboxBitmap(GetType(ReplicatorActivity), "Resources.Replicator.png"), Designer(GetType(ReplicatorDesigner), GetType(IDesigner)), WorkflowDebuggerStepping(WorkflowDebuggerSteppingOption.Concurrent), DefaultEvent("Initialized"), ActivityValidator(GetType(ReplicatorValidator))> _
    Public NotInheritable Class ReplicatorActivity
        Inherits CompositeActivity
        ' Events
        <MergableProperty(False), SRCategory("Handlers"), SRDescription("OnGeneratorChildCompletedDescr")> _
        Public Custom Event ChildCompleted As EventHandler([Of] ReplicatorChildEventArgs)
            AddHandler(ByVal value As EventHandler([Of] ReplicatorChildEventArgs))
                MyBase.AddHandler(ReplicatorActivity.ChildCompletedEvent, value)
            End AddHandler
            RemoveHandler(ByVal value As EventHandler([Of] ReplicatorChildEventArgs))
                MyBase.RemoveHandler(ReplicatorActivity.ChildCompletedEvent, value)
            End RemoveHandler
        End Event
        <SRCategory("Handlers"), SRDescription("OnGeneratorChildInitializedDescr"), MergableProperty(False)> _
        Public Custom Event ChildInitialized As EventHandler([Of] ReplicatorChildEventArgs)
            AddHandler(ByVal value As EventHandler([Of] ReplicatorChildEventArgs))
                MyBase.AddHandler(ReplicatorActivity.ChildInitializedEvent, value)
            End AddHandler
            RemoveHandler(ByVal value As EventHandler([Of] ReplicatorChildEventArgs))
                MyBase.RemoveHandler(ReplicatorActivity.ChildInitializedEvent, value)
            End RemoveHandler
        End Event
        <SRCategory("Handlers"), MergableProperty(False), SRDescription("OnCompletedDescr")> _
        Public Custom Event Completed As EventHandler
            AddHandler(ByVal value As EventHandler)
                MyBase.AddHandler(ReplicatorActivity.CompletedEvent, value)
            End AddHandler
            RemoveHandler(ByVal value As EventHandler)
                MyBase.RemoveHandler(ReplicatorActivity.CompletedEvent, value)
            End RemoveHandler
        End Event
        <SRDescription("OnInitializedDescr"), SRCategory("Handlers"), MergableProperty(False)> _
        Public Custom Event Initialized As EventHandler
            AddHandler(ByVal value As EventHandler)
                MyBase.AddHandler(ReplicatorActivity.InitializedEvent, value)
            End AddHandler
            RemoveHandler(ByVal value As EventHandler)
                MyBase.RemoveHandler(ReplicatorActivity.InitializedEvent, value)
            End RemoveHandler
        End Event

        ' Methods
        Public Sub New()
        End Sub

        Public Sub New(ByVal name As String)
            MyBase.New(name)
        End Sub

        Private Function Add(ByVal value As Object) As Integer
            If (MyBase.ExecutionStatus <> ActivityExecutionStatus.Executing) Then
                Throw New InvalidOperationException(SR.GetString("Error_ReplicatorNotExecuting"))
            End If
            If (Me.ActivityState Is Nothing) Then
                Throw New InvalidOperationException(SR.GetString("Error_ReplicatorNotInitialized"))
            End If
            Dim item As New ChildExecutionStateInfo(value)
            Me.ActivityState.Add(item)
            Dim index As Integer = (Me.ActivityState.AbsoluteCount - 1)
            Me.ScheduleExecutionIfNeeded(item, index)
            Return index
        End Function

        Protected Overrides Function Cancel(ByVal executionContext As ActivityExecutionContext) As ActivityExecutionStatus
            If (executionContext Is Nothing) Then
                Throw New ArgumentNullException("executionContext")
            End If
            Me.TryCancelChildren(executionContext)
            If Me.ActivityState.IsChildActive Then
                Return MyBase.ExecutionStatus
            End If
            If (MyBase.ExecutionStatus = ActivityExecutionStatus.Faulting) Then
                If Me.ActivityState.AttemptedCloseWhileFaulting Then
                    Return ActivityExecutionStatus.Closed
                End If
                Me.ActivityState.AttemptedCloseWhileFaulting = True
            End If
            MyBase.RaiseEvent(ReplicatorActivity.CompletedEvent, Me, EventArgs.Empty)
            Return ActivityExecutionStatus.Closed
        End Function

        Private Sub CancelChildExecution(ByVal executionContext As ActivityExecutionContext, ByVal childStateInfo As ChildExecutionStateInfo)
            If (childStateInfo.Status <> ChildRunStatus.Running) Then
                Me.ActivityState.Remove(childStateInfo)
            Else
                Me.TryCancelChild(executionContext, childStateInfo)
            End If
        End Sub

        Private Sub Clear()
            If (MyBase.ExecutionStatus <> ActivityExecutionStatus.Executing) Then
                Throw New InvalidOperationException(SR.GetString("Error_ReplicatorNotExecuting"))
            End If
            If (Me.ActivityState Is Nothing) Then
                Throw New InvalidOperationException(SR.GetString("Error_ReplicatorNotInitialized"))
            End If
            Do While (Me.ActivityState.AbsoluteCount <> 0)
                Me.RemoveAt(0)
            Loop
        End Sub

        Protected Overrides Function Execute(ByVal executionContext As ActivityExecutionContext) As ActivityExecutionStatus
            If (executionContext Is Nothing) Then
                Throw New ArgumentNullException("executionContext")
            End If
            Me.ActivityState = New ReplicatorStateInfo
            MyBase.RaiseEvent(ReplicatorActivity.InitializedEvent, Me, EventArgs.Empty)
            If (Not Me.InitialChildData Is Nothing) Then
                Dim i As Integer
                For i = 0 To Me.InitialChildData.Count - 1
                    Me.Add(Me.InitialChildData.Item(i))
                Next i
            End If
            Dim flag As Boolean = (Me.UntilCondition Is Nothing)
            If ((Not Me.UntilCondition Is Nothing) AndAlso Me.UntilCondition.Evaluate(Me, executionContext)) Then
                flag = True
            ElseIf (Me.ActivityState.Count <> 0) Then
                flag = False
            End If
            If flag Then
                Me.ActivityState.CompletionConditionTrueAlready = True
                If Not Me.TryCancelChildren(executionContext) Then
                    MyBase.RaiseEvent(ReplicatorActivity.CompletedEvent, Me, EventArgs.Empty)
                    Return ActivityExecutionStatus.Closed
                End If
            End If
            Return ActivityExecutionStatus.Executing
        End Function

        Private Sub ExecuteTemplate(ByVal executionContext As ActivityExecutionContext, ByVal childStateInfo As ChildExecutionStateInfo)
            Dim executionContextManager As ActivityExecutionContextManager = executionContext.ExecutionContextManager
            Dim childContext As ActivityExecutionContext = executionContextManager.CreateExecutionContext(MyBase.EnabledActivities.Item(0))
            childStateInfo.RunId = childContext.ContextGuid
            childStateInfo.Status = ChildRunStatus.Running
            Try 
                MyBase.RaiseGenericEvent([Of] ReplicatorChildEventArgs)(ReplicatorActivity.ChildInitializedEvent, Me, New ReplicatorChildEventArgs(childStateInfo.InstanceData, childContext.Activity))
            Catch obj1 As Object
                childStateInfo.RunId = Guid.Empty
                childStateInfo.Status = ChildRunStatus.Completed
                executionContextManager.CompleteExecutionContext(childContext)
                Throw
            End Try
            childContext.ExecuteActivity(childContext.Activity)
            childContext.Activity.RegisterForStatusChange(Activity.ClosedEvent, New ReplicatorSubscriber(Me, childContext.ContextGuid))
        End Sub

        Private Function GetExecutionContext(ByVal contextManager As ActivityExecutionContextManager, ByVal contextIdGuid As Guid) As ActivityExecutionContext
            Dim context As ActivityExecutionContext
            For Each context In contextManager.ExecutionContexts
                If (context.ContextGuid = contextIdGuid) Then
                    Return context
                End If
            Next
            Return Nothing
        End Function

        Private Sub HandleChildUpdateOperation(ByVal sender As Object, ByVal e As ReplicatorInterActivityEventArgs)
            If (sender Is Nothing) Then
                Throw New ArgumentNullException("sender")
            End If
            Dim executionContext As ActivityExecutionContext = [TryCast](sender,ActivityExecutionContext)
            If (executionContext Is Nothing) Then
                Throw New ArgumentException(SR.Error_SenderMustBeActivityExecutionContext, "sender")
            End If
            If (MyBase.ExecutionStatus = ActivityExecutionStatus.Executing) Then
                If Not e.IsAdd Then
                    Me.CancelChildExecution(executionContext, e.ChildStateInfo)
                Else
                    Me.ExecuteTemplate(executionContext, e.ChildStateInfo)
                End If
            End If
        End Sub

        Private Sub HandleStatusChange(ByVal executionContext As ActivityExecutionContext, ByVal e As ActivityExecutionStatusChangedEventArgs, ByVal subscriber As ReplicatorSubscriber)
            Dim num As Integer = Me.ActivityState.FindIndexOfChildStateInfo(subscriber.RunIdentifier)
            If (num <> -1) Then
                Dim item As ChildExecutionStateInfo = Me.ActivityState.Item(num)
                Dim markedForRemoval As Boolean = item.MarkedForRemoval
                Try 
                    Try 
                        MyBase.RaiseGenericEvent([Of] ReplicatorChildEventArgs)(ReplicatorActivity.ChildCompletedEvent, Me, New ReplicatorChildEventArgs(item.InstanceData, e.Activity))
                        e.Activity.UnregisterForStatusChange(Activity.ClosedEvent, subscriber)
                    Finally
                        Dim executionContextManager As ActivityExecutionContextManager = executionContext.ExecutionContextManager
                        Dim childContext As ActivityExecutionContext = executionContextManager.GetExecutionContext(e.Activity)
                        executionContextManager.CompleteExecutionContext(childContext)
                    End Try
                    If Not Me.ActivityState.CompletionConditionTrueAlready Then
                        Me.ActivityState.CompletionConditionTrueAlready = ((Not Me.UntilCondition Is Nothing) AndAlso Me.UntilCondition.Evaluate(Me, executionContext))
                    End If
                Finally
                    item.RunId = Guid.Empty
                    item.Status = ChildRunStatus.Completed
                    If markedForRemoval Then
                        Me.ActivityState.Remove(item)
                        num -= 1
                    End If
                End Try
                If Not Me.ActivityState.IsChildActive Then
                    If (((MyBase.ExecutionStatus = ActivityExecutionStatus.Canceling) OrElse (MyBase.ExecutionStatus = ActivityExecutionStatus.Faulting)) OrElse Me.ActivityState.CompletionConditionTrueAlready) Then
                        MyBase.RaiseEvent(ReplicatorActivity.CompletedEvent, Me, EventArgs.Empty)
                        executionContext.CloseActivity
                        Return
                    End If
                ElseIf (((MyBase.ExecutionStatus <> ActivityExecutionStatus.Canceling) AndAlso (MyBase.ExecutionStatus <> ActivityExecutionStatus.Faulting)) AndAlso Me.ActivityState.CompletionConditionTrueAlready) Then
                    Me.TryCancelChildren(executionContext)
                    Return
                End If
                Select Case Me.ExecutionType
                    Case ExecutionType.Sequence
                        If (num >= (Me.ActivityState.Count - 1)) Then
                            If ((Me.UntilCondition Is Nothing) OrElse Me.UntilCondition.Evaluate(Me, executionContext)) Then
                                MyBase.RaiseEvent(ReplicatorActivity.CompletedEvent, Me, EventArgs.Empty)
                                executionContext.CloseActivity
                                Return
                            End If
                            Exit Select
                        End If
                        Me.ExecuteTemplate(executionContext, Me.ActivityState.Item((num + 1)))
                        Return
                    Case ExecutionType.Parallel
                        If (Me.ActivityState.IsChildActive OrElse ((Not Me.UntilCondition Is Nothing) AndAlso Not Me.UntilCondition.Evaluate(Me, executionContext))) Then
                            Exit Select
                        End If
                        MyBase.RaiseEvent(ReplicatorActivity.CompletedEvent, Me, EventArgs.Empty)
                        executionContext.CloseActivity
                        Return
                    Case Else
                        Throw New InvalidOperationException(SR.GetString("Error_ReplicatorInvalidExecutionType"))
                End Select
            End If
        End Sub

        Private Function IndexOf(ByVal value As Object) As Integer
            If (MyBase.ExecutionStatus <> ActivityExecutionStatus.Executing) Then
                Throw New InvalidOperationException(SR.GetString("Error_ReplicatorNotExecuting"))
            End If
            If (Me.ActivityState Is Nothing) Then
                Throw New InvalidOperationException(SR.GetString("Error_ReplicatorNotInitialized"))
            End If
            Dim num As Integer = 0
            Dim i As Integer
            For i = 0 To Me.ActivityState.Count - 1
                Dim info As ChildExecutionStateInfo = Me.ActivityState.Item(i)
                If Not info.MarkedForRemoval Then
                    If Object.Equals(info.InstanceData, value) Then
                        Return num
                    End If
                    num += 1
                End If
            Next i
            Return -1
        End Function

        Private Sub Insert(ByVal index As Integer, ByVal value As Object)
            If (value Is Nothing) Then
                Throw New ArgumentNullException("value")
            End If
            If (MyBase.ExecutionStatus <> ActivityExecutionStatus.Executing) Then
                Throw New InvalidOperationException(SR.GetString("Error_ReplicatorNotExecuting"))
            End If
            If (Me.ActivityState Is Nothing) Then
                Throw New InvalidOperationException(SR.GetString("Error_ReplicatorNotInitialized"))
            End If
            If ((index < 0) OrElse (index > Me.ActivityState.AbsoluteCount)) Then
                Throw New ArgumentOutOfRangeException("index")
            End If
            Dim info As New ChildExecutionStateInfo(value)
            Me.ActivityState.Insert(index, info, False)
            Me.ScheduleExecutionIfNeeded(info, index)
        End Sub

        Public Function IsExecuting(ByVal index As Integer) As Boolean
            If (Me.ActivityState Is Nothing) Then
                Return False
            End If
            If ((index < 0) OrElse (index >= Me.ActivityState.AbsoluteCount)) Then
                Throw New ArgumentOutOfRangeException("index")
            End If
            Dim info As ChildExecutionStateInfo = Me.ActivityState.Item(index, False)
            If (info.Status <> ChildRunStatus.PendingExecute) Then
                Return (info.Status = ChildRunStatus.Running)
            End If
            Return True
        End Function

        Protected Overrides Sub OnClosed(ByVal provider As IServiceProvider)
        End Sub

        Private Sub Remove(ByVal obj As Object)
            Dim index As Integer = Me.IndexOf(obj)
            If (index >= 0) Then
                Me.RemoveAt(index)
            End If
        End Sub

        Private Sub RemoveAt(ByVal index As Integer)
            If (MyBase.ExecutionStatus <> ActivityExecutionStatus.Executing) Then
                Throw New InvalidOperationException(SR.GetString("Error_ReplicatorNotExecuting"))
            End If
            If (Me.ActivityState Is Nothing) Then
                Throw New InvalidOperationException(SR.GetString("Error_ReplicatorNotInitialized"))
            End If
            If ((index < 0) OrElse (index >= Me.ActivityState.AbsoluteCount)) Then
                Throw New ArgumentOutOfRangeException("index")
            End If
            Dim item As ChildExecutionStateInfo = Me.ActivityState.Item(index, False)
            If ((item.Status = ChildRunStatus.Completed) OrElse (item.Status = ChildRunStatus.Created)) Then
                Me.ActivityState.Remove(item)
            Else
                item.MarkedForRemoval = True
                MyBase.Invoke([Of] ReplicatorInterActivityEventArgs)(New EventHandler([Of] ReplicatorInterActivityEventArgs)(AddressOf Me.HandleChildUpdateOperation), New ReplicatorInterActivityEventArgs(item, False))
            End If
        End Sub

        Private Sub ScheduleExecutionIfNeeded(ByVal childStateInfo As ChildExecutionStateInfo, ByVal index As Integer)
            Dim flag As Boolean = (Me.ExecutionType = ExecutionType.Parallel)
            If Not flag Then
                Dim absoluteCount As Integer = Me.ActivityState.AbsoluteCount
                If (((index = 0) AndAlso (absoluteCount = 1)) OrElse ((index = (absoluteCount - 1)) AndAlso (Me.ActivityState.Item((absoluteCount - 2), False).Status = ChildRunStatus.Completed))) Then
                    flag = True
                End If
            End If
            If flag Then
                childStateInfo.Status = ChildRunStatus.PendingExecute
                MyBase.Invoke([Of] ReplicatorInterActivityEventArgs)(New EventHandler([Of] ReplicatorInterActivityEventArgs)(AddressOf Me.HandleChildUpdateOperation), New ReplicatorInterActivityEventArgs(childStateInfo, True))
            End If
        End Sub

        Private Function TryCancelChild(ByVal outerProvider As ActivityExecutionContext, ByVal childStateInfo As ChildExecutionStateInfo) As Boolean
            Dim flag As Boolean = False
            Dim executionContextManager As ActivityExecutionContextManager = outerProvider.ExecutionContextManager
            Dim executionContext As ActivityExecutionContext = Me.GetExecutionContext(executionContextManager, childStateInfo.RunId)
            If (Not executionContext Is Nothing) Then
                Select Case executionContext.Activity.ExecutionStatus
                    Case ActivityExecutionStatus.Executing
                        executionContext.CancelActivity(executionContext.Activity)
                        Return True
                    Case ActivityExecutionStatus.Canceling, ActivityExecutionStatus.Faulting
                        Return True
                    Case ActivityExecutionStatus.Closed, ActivityExecutionStatus.Compensating
                        Return flag
                End Select
                Return flag
            End If
            If ((MyBase.ExecutionStatus <> ActivityExecutionStatus.Executing) AndAlso (childStateInfo.Status = ChildRunStatus.PendingExecute)) Then
                childStateInfo.Status = ChildRunStatus.Completed
            End If
            Return flag
        End Function

        Private Function TryCancelChildren(ByVal executionContext As ActivityExecutionContext) As Boolean
            If (Me.ActivityState Is Nothing) Then
                Return False
            End If
            Dim activityState As ReplicatorStateInfo = Me.ActivityState
            Dim flag As Boolean = False
            Dim i As Integer
            For i = 0 To activityState.Count - 1
                If Me.TryCancelChild(executionContext, activityState.Item(i)) Then
                    flag = True
                End If
            Next i
            Return flag
        End Function


        ' Properties
        Private Property ActivityState As ReplicatorStateInfo
            Get
                Return DirectCast(MyBase.GetValue(ReplicatorActivity.ActivityStateProperty), ReplicatorStateInfo)
            End Get
            Set(ByVal value As ReplicatorStateInfo)
                MyBase.SetValue(ReplicatorActivity.ActivityStateProperty, value)
            End Set
        End Property

        <DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), Browsable(False)> _
        Public ReadOnly Property AllChildrenComplete As Boolean
            Get
                If (Not Me.ActivityState Is Nothing) Then
                    Return Not Me.ActivityState.IsChildActive
                End If
                Return True
            End Get
        End Property

        <DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), Browsable(False)> _
        Public ReadOnly Property CurrentChildData As IList
            Get
                If (Me.childDataList Is Nothing) Then
                    Me.childDataList = New ReplicatorChildInstanceList(Me)
                End If
                Return Me.childDataList
            End Get
        End Property

        <DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), Browsable(False)> _
        Public ReadOnly Property CurrentIndex As Integer
            Get
                If (Me.ActivityState Is Nothing) Then
                    Return -1
                End If
                If (Me.ExecutionType = ExecutionType.Sequence) Then
                    Return Me.ActivityState.CurrentIndex
                End If
                Return (Me.ActivityState.AbsoluteCount - 1)
            End Get
        End Property

        <DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), Browsable(False)> _
        Public ReadOnly Property DynamicActivities As ICollection([Of] Activity)
            Get
                If (MyBase.EnabledActivities.Count > 0) Then
                    Return MyBase.GetDynamicActivities(MyBase.EnabledActivities.Item(0))
                End If
                Return New Activity(0  - 1) {}
            End Get
        End Property

        <SRCategory("Properties"), SRDescription("ExecutionTypeDescr"), DesignerSerializationVisibility(DesignerSerializationVisibility.Visible), Browsable(True)> _
        Public Property ExecutionType As ExecutionType
            Get
                Return DirectCast(MyBase.GetValue(ReplicatorActivity.ExecutionTypeProperty), ExecutionType)
            End Get
            Set(ByVal value As ExecutionType)
                If ((value <> ExecutionType.Sequence) AndAlso (value <> ExecutionType.Parallel)) Then
                    Throw New ArgumentOutOfRangeException("value")
                End If
                If ((Not Me.ActivityState Is Nothing) AndAlso Me.ActivityState.IsChildActive) Then
                    Throw New InvalidOperationException(SR.GetString("Error_ReplicatorChildRunning"))
                End If
                MyBase.SetValue(ReplicatorActivity.ExecutionTypeProperty, value)
            End Set
        End Property

        <Browsable(True), SRCategory("Properties"), DefaultValue(CStr(Nothing)), Editor(GetType(BindUITypeEditor), GetType(UITypeEditor)), SRDescription("InitialChildDataDescr"), DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)> _
        Public Property InitialChildData As IList
            Get
                Return [TryCast](MyBase.GetValue(ReplicatorActivity.InitialChildDataProperty),IList)
            End Get
            Set(ByVal value As IList)
                MyBase.SetValue(ReplicatorActivity.InitialChildDataProperty, value)
            End Set
        End Property

        <SRDescription("ReplicatorUntilConditionDescr"), DefaultValue(CStr(Nothing)), SRCategory("Conditions")> _
        Public Property UntilCondition As ActivityCondition
            Get
                Return [TryCast](MyBase.GetValue(ReplicatorActivity.UntilConditionProperty),ActivityCondition)
            End Get
            Set(ByVal value As ActivityCondition)
                MyBase.SetValue(ReplicatorActivity.UntilConditionProperty, value)
            End Set
        End Property


        ' Fields
        Private Shared ActivityStateProperty As DependencyProperty = DependencyProperty.Register("ActivityState", GetType(ReplicatorStateInfo), GetType(ReplicatorActivity))
        Public Shared ReadOnly ChildCompletedEvent As DependencyProperty = DependencyProperty.Register("ChildCompleted", GetType(EventHandler([Of] ReplicatorChildEventArgs)), GetType(ReplicatorActivity))
        Private childDataList As ReplicatorChildInstanceList
        Public Shared ReadOnly ChildInitializedEvent As DependencyProperty = DependencyProperty.Register("ChildInitialized", GetType(EventHandler([Of] ReplicatorChildEventArgs)), GetType(ReplicatorActivity))
        Public Shared ReadOnly CompletedEvent As DependencyProperty = DependencyProperty.Register("Completed", GetType(EventHandler), GetType(ReplicatorActivity))
        Public Shared ReadOnly ExecutionTypeProperty As DependencyProperty = DependencyProperty.Register("ExecutionType", GetType(ExecutionType), GetType(ReplicatorActivity), New PropertyMetadata(ExecutionType.Sequence))
        Public Shared ReadOnly InitialChildDataProperty As DependencyProperty = DependencyProperty.Register("InitialChildData", GetType(IList), GetType(ReplicatorActivity))
        Public Shared ReadOnly InitializedEvent As DependencyProperty = DependencyProperty.Register("Initialized", GetType(EventHandler), GetType(ReplicatorActivity))
        Public Shared ReadOnly UntilConditionProperty As DependencyProperty = DependencyProperty.Register("UntilCondition", GetType(ActivityCondition), GetType(ReplicatorActivity), New PropertyMetadata(DependencyPropertyOptions.Metadata))

        ' Nested Types
        <Serializable> _
        Private Class ChildExecutionStateInfo
            ' Methods
            Friend Sub New(ByVal instanceData As Object)
                Me.data = instanceData
                Me.markedForRemoval = False
                Me.status = ChildRunStatus.Created
            End Sub


            ' Properties
            Friend Property InstanceData As Object
                Get
                    Return Me.data
                End Get
                Set(ByVal value As Object)
                    Me.data = value
                End Set
            End Property

            Friend Property MarkedForRemoval As Boolean
                Get
                    Return Me.markedForRemoval
                End Get
                Set(ByVal value As Boolean)
                    Me.markedForRemoval = value
                End Set
            End Property

            Friend Property RunId As Guid
                Get
                    Return Me.runId
                End Get
                Set(ByVal value As Guid)
                    Me.runId = value
                End Set
            End Property

            Friend Property Status As ChildRunStatus
                Get
                    Return Me.status
                End Get
                Set(ByVal value As ChildRunStatus)
                    Me.status = value
                End Set
            End Property


            ' Fields
            Private data As Object
            Private markedForRemoval As Boolean
            Private runId As Guid
            Private status As ChildRunStatus
        End Class

        Private Enum ChildRunStatus As Byte
            ' Fields
            Completed = 3
            Created = 0
            PendingExecute = 1
            Running = 2
        End Enum

        <Serializable> _
        Private NotInheritable Class ReplicatorChildInstanceList
            Implements IList, ICollection, IEnumerable
            ' Methods
            Friend Sub New(ByVal replicatorActivity As ReplicatorActivity)
                Me.replicatorActivity = replicatorActivity
            End Sub

            Private Sub System.Collections.ICollection.CopyTo(ByVal array As Array, ByVal index As Integer) Implements ICollection.CopyTo
                If (Me.replicatorActivity Is Nothing) Then
                    Throw New InvalidOperationException(SR.GetString("Error_ReplicatorDisconnected"))
                End If
                If (Me.replicatorActivity.ExecutionStatus <> ActivityExecutionStatus.Executing) Then
                    Throw New InvalidOperationException(SR.GetString("Error_ReplicatorNotExecuting"))
                End If
                If (Me.replicatorActivity.ActivityState Is Nothing) Then
                    Throw New InvalidOperationException(SR.GetString("Error_ReplicatorNotInitialized"))
                End If
                If (array Is Nothing) Then
                    Throw New ArgumentNullException("array")
                End If
                If (array.Rank <> 1) Then
                    Throw New ArgumentException(SR.GetString("Error_MultiDimensionalArray"), "array")
                End If
                If (index < 0) Then
                    Throw New ArgumentOutOfRangeException("index")
                End If
                If ((array.Length - index) < Me.replicatorActivity.ActivityState.AbsoluteCount) Then
                    Throw New ArgumentException(SR.GetString("Error_InsufficientArrayPassedIn"), "array")
                End If
                Dim i As Integer
                For i = 0 To Me.replicatorActivity.ActivityState.AbsoluteCount - 1
                    array.SetValue(Me.replicatorActivity.ActivityState.Item(i, False).InstanceData, CInt((i + index)))
                Next i
            End Sub

            Private Function System.Collections.IEnumerable.GetEnumerator() As IEnumerator Implements IEnumerable.GetEnumerator
                Return New GetEnumerator>d__0(0) { _
                    .<>4__this = Me _
                }
            End Function

            Private Function System.Collections.IList.Add(ByVal value As Object) As Integer Implements IList.Add
                If (Me.replicatorActivity Is Nothing) Then
                    Throw New InvalidOperationException(SR.GetString("Error_ReplicatorDisconnected"))
                End If
                Return Me.replicatorActivity.Add(value)
            End Function

            Private Sub System.Collections.IList.Clear() Implements IList.Clear
                If (Me.replicatorActivity Is Nothing) Then
                    Throw New InvalidOperationException(SR.GetString("Error_ReplicatorDisconnected"))
                End If
                Me.replicatorActivity.Clear
            End Sub

            Private Function System.Collections.IList.Contains(ByVal value As Object) As Boolean Implements IList.Contains
                If (Me.replicatorActivity Is Nothing) Then
                    Throw New InvalidOperationException(SR.GetString("Error_ReplicatorDisconnected"))
                End If
                Return (Me.replicatorActivity.IndexOf(value) <> -1)
            End Function

            Private Function System.Collections.IList.IndexOf(ByVal value As Object) As Integer Implements IList.IndexOf
                If (Me.replicatorActivity Is Nothing) Then
                    Throw New InvalidOperationException(SR.GetString("Error_ReplicatorDisconnected"))
                End If
                Return Me.replicatorActivity.IndexOf(value)
            End Function

            Private Sub System.Collections.IList.Insert(ByVal index As Integer, ByVal value As Object) Implements IList.Insert
                If (Me.replicatorActivity Is Nothing) Then
                    Throw New InvalidOperationException(SR.GetString("Error_ReplicatorDisconnected"))
                End If
                Me.replicatorActivity.Insert(index, value)
            End Sub

            Private Sub System.Collections.IList.Remove(ByVal value As Object) Implements IList.Remove
                If (Me.replicatorActivity Is Nothing) Then
                    Throw New InvalidOperationException(SR.GetString("Error_ReplicatorDisconnected"))
                End If
                Me.replicatorActivity.Remove(value)
            End Sub

            Private Sub System.Collections.IList.RemoveAt(ByVal index As Integer) Implements IList.RemoveAt
                If (Me.replicatorActivity Is Nothing) Then
                    Throw New InvalidOperationException(SR.GetString("Error_ReplicatorDisconnected"))
                End If
                Me.replicatorActivity.RemoveAt(index)
            End Sub


            ' Properties
            Private ReadOnly Property System.Collections.ICollection.Count As Integer
                Get
                    If (Me.replicatorActivity Is Nothing) Then
                        Throw New InvalidOperationException(SR.GetString("Error_ReplicatorDisconnected"))
                    End If
                    If (Me.replicatorActivity.ExecutionStatus <> ActivityExecutionStatus.Executing) Then
                        Throw New InvalidOperationException(SR.GetString("Error_ReplicatorNotExecuting"))
                    End If
                    If (Me.replicatorActivity.ActivityState Is Nothing) Then
                        Throw New InvalidOperationException(SR.GetString("Error_ReplicatorNotInitialized"))
                    End If
                    Return Me.replicatorActivity.ActivityState.AbsoluteCount
                End Get
            End Property

            Private ReadOnly Property System.Collections.ICollection.IsSynchronized As Boolean
                Get
                    Return False
                End Get
            End Property

            Private ReadOnly Property System.Collections.ICollection.SyncRoot As Object
                Get
                    Throw New NotImplementedException
                End Get
            End Property

            Private ReadOnly Property System.Collections.IList.IsFixedSize As Boolean
                Get
                    Return False
                End Get
            End Property

            Private ReadOnly Property System.Collections.IList.IsReadOnly As Boolean
                Get
                    Return False
                End Get
            End Property

            Private Property System.Collections.IList.Item(ByVal index As Integer) As Object
                Get
                    If (Me.replicatorActivity Is Nothing) Then
                        Throw New InvalidOperationException(SR.GetString("Error_ReplicatorDisconnected"))
                    End If
                    If (Me.replicatorActivity.ExecutionStatus <> ActivityExecutionStatus.Executing) Then
                        Throw New InvalidOperationException(SR.GetString("Error_ReplicatorNotExecuting"))
                    End If
                    If (Me.replicatorActivity.ActivityState Is Nothing) Then
                        Throw New InvalidOperationException(SR.GetString("Error_ReplicatorNotInitialized"))
                    End If
                    Return Me.replicatorActivity.ActivityState.Item(index, False).InstanceData
                End Get
                Set(ByVal value As Object)
                    If (Me.replicatorActivity Is Nothing) Then
                        Throw New InvalidOperationException(SR.GetString("Error_ReplicatorDisconnected"))
                    End If
                    If (Me.replicatorActivity.ExecutionStatus <> ActivityExecutionStatus.Executing) Then
                        Throw New InvalidOperationException(SR.GetString("Error_ReplicatorNotExecuting"))
                    End If
                    If (Me.replicatorActivity.ActivityState Is Nothing) Then
                        Throw New InvalidOperationException(SR.GetString("Error_ReplicatorNotInitialized"))
                    End If
                    Me.replicatorActivity.ActivityState.Item(index, False).InstanceData = value
                End Set
            End Property


            ' Fields
            Private replicatorActivity As ReplicatorActivity

            ' Nested Types
            <CompilerGenerated> _
            Private NotInheritable Class GetEnumerator>d__0
                Implements IEnumerator([Of] Object), IEnumerator, IDisposable
                ' Methods
                <DebuggerHidden> _
                Public Sub New(ByVal <>1__state As Integer)
                    Me.<>1__state = <>1__state
                End Sub

                Private Function MoveNext() As Boolean Implements IEnumerator.MoveNext
                    Select Case Me.<>1__state
                        Case 0
                            Me.<>1__state = -1
                            If (Me.<>4__this.replicatorActivity Is Nothing) Then
                                Throw New InvalidOperationException(SR.GetString("Error_ReplicatorDisconnected"))
                            End If
                            If (Me.<>4__this.replicatorActivity.ExecutionStatus <> ActivityExecutionStatus.Executing) Then
                                Throw New InvalidOperationException(SR.GetString("Error_ReplicatorNotExecuting"))
                            End If
                            If (Me.<>4__this.replicatorActivity.ActivityState Is Nothing) Then
                                Throw New InvalidOperationException(SR.GetString("Error_ReplicatorNotInitialized"))
                            End If
                            Me.<i>5__1 = 0
                            Do While (Me.<i>5__1 < Me.<>4__this.replicatorActivity.ActivityState.AbsoluteCount)
                                Me.<>2__current = Me.<>4__this.replicatorActivity.ActivityState.Item(Me.<i>5__1, False).InstanceData
                                Me.<>1__state = 1
                                Return True
                            Label_00BC:
                                Me.<>1__state = -1
                                Me.<i>5__1 += 1
                            Loop
                            Exit Select
                        Case 1
                            goto Label_00BC
                    End Select
                    Return False
                End Function

                <DebuggerHidden> _
                Private Sub System.Collections.IEnumerator.Reset() Implements IEnumerator.Reset
                    Throw New NotSupportedException
                End Sub

                Private Sub System.IDisposable.Dispose() Implements IDisposable.Dispose
                End Sub


                ' Properties
                Private ReadOnly Property System.Collections.Generic.IEnumerator<System.Object>.Current As Object
                    <DebuggerHidden> _
                    Get
                        Return Me.<>2__current
                    End Get
                End Property

                Private ReadOnly Property System.Collections.IEnumerator.Current As Object
                    <DebuggerHidden> _
                    Get
                        Return Me.<>2__current
                    End Get
                End Property


                ' Fields
                Private <>1__state As Integer
                Private <>2__current As Object
                Public <>4__this As ReplicatorChildInstanceList
                Public <i>5__1 As Integer
            End Class
        End Class

        Private NotInheritable Class ReplicatorInterActivityEventArgs
            Inherits EventArgs
            ' Methods
            Friend Sub New(ByVal childStateInfo As ChildExecutionStateInfo, ByVal isAdd As Boolean)
                Me.childStateInfo = childStateInfo
                Me.isAdd = isAdd
            End Sub


            ' Properties
            Friend ReadOnly Property ChildStateInfo As ChildExecutionStateInfo
                Get
                    Return Me.childStateInfo
                End Get
            End Property

            Friend ReadOnly Property IsAdd As Boolean
                Get
                    Return Me.isAdd
                End Get
            End Property


            ' Fields
            Private childStateInfo As ChildExecutionStateInfo
            Private isAdd As Boolean
        End Class

        <Serializable, DefaultMember("Item")> _
        Private Class ReplicatorStateInfo
            Inherits List(Of ChildExecutionStateInfo)
            ' Methods
            Friend Function Add(ByVal value As ChildExecutionStateInfo, ByVal includeStaleEntries As Boolean) As Integer
                MyBase.Add(value)
                If includeStaleEntries Then
                    Return (MyBase.Count - 1)
                End If
                Return (Me.AbsoluteCount - 1)
            End Function

            Friend Function FindIndexOfChildStateInfo(ByVal runId As Guid) As Integer
                Dim i As Integer
                For i = 0 To MyBase.Count - 1
                    Dim info As ChildExecutionStateInfo = MyBase.Item(i)
                    If (info.RunId = runId) Then
                        Return i
                    End If
                Next i
                Throw New IndexOutOfRangeException
            End Function

            Friend Sub Insert(ByVal index As Integer, ByVal value As ChildExecutionStateInfo, ByVal includeStaleEntries As Boolean)
                If includeStaleEntries Then
                    MyBase.Insert(index, value)
                Else
                    Dim num As Integer = 0
                    num = 0
                    Do While ((num < MyBase.Count) AndAlso (index > 0))
                        If Not MyBase.Item(num).MarkedForRemoval Then
                            index -= 1
                        End If
                        num += 1
                    Loop
                    If (index <> 0) Then
                        Throw New IndexOutOfRangeException
                    End If
                    MyBase.Insert(num, value)
                End If
            End Sub


            ' Properties
            Friend ReadOnly Property AbsoluteCount As Integer
                Get
                    Dim num As Integer = 0
                    Dim num2 As Integer = 0
                    Do While (num2 < MyBase.Count)
                        If Not MyBase.Item(num2++).MarkedForRemoval Then
                            num += 1
                        End If
                    Loop
                    Return num
                End Get
            End Property

            Friend ReadOnly Property CurrentIndex As Integer
                Get
                    Dim i As Integer
                    For i = 0 To Me.AbsoluteCount - 1
                        If (Me.Item(i, False).RunId <> Guid.Empty) Then
                            Return i
                        End If
                    Next i
                    Return (Me.AbsoluteCount - 1)
                End Get
            End Property

            Friend ReadOnly Property IsChildActive As Boolean
                Get
                    Dim i As Integer
                    For i = 0 To MyBase.Count - 1
                        Dim info As ChildExecutionStateInfo = MyBase.Item(i)
                        If ((info.Status = ChildRunStatus.Running) OrElse (info.Status = ChildRunStatus.PendingExecute)) Then
                            Return True
                        End If
                    Next i
                    Return False
                End Get
            End Property

            Friend ReadOnly Default Property Item(ByVal index As Integer, ByVal includeStaleEntries As Boolean) As ChildExecutionStateInfo
                Get
                    If includeStaleEntries Then
                        Return MyBase.Item(index)
                    End If
                    Dim i As Integer
                    For i = 0 To MyBase.Count - 1
                        If (Not MyBase.Item(i).MarkedForRemoval AndAlso (index-- = 0)) Then
                            Return MyBase.Item(i)
                        End If
                    Next i
                    Throw New IndexOutOfRangeException
                End Get
            End Property


            ' Fields
            Friend AttemptedCloseWhileFaulting As Boolean
            Friend CompletionConditionTrueAlready As Boolean
        End Class

        <Serializable> _
        Private Class ReplicatorSubscriber
            Implements IActivityEventListener([Of] ActivityExecutionStatusChangedEventArgs)
            ' Methods
            Friend Sub New(ByVal ownerActivity As Activity, ByVal runIdentifier As Guid)
                Me.runId = runIdentifier
            End Sub

            Public Overrides Function Equals(ByVal obj As Object) As Boolean
                Dim subscriber As ReplicatorSubscriber = [TryCast](obj,ReplicatorSubscriber)
                Return (((Not subscriber Is Nothing) AndAlso MyBase.Equals(obj)) AndAlso Me.runId.Equals(subscriber.runId))
            End Function

            Public Overrides Function GetHashCode() As Integer
                Return (MyBase.GetHashCode Xor Me.runId.GetHashCode)
            End Function

            Private Sub System.Workflow.ComponentModel.IActivityEventListener<System.Workflow.ComponentModel.ActivityExecutionStatusChangedEventArgs>.OnEvent(ByVal sender As Object, ByVal e As ActivityExecutionStatusChangedEventArgs) Implements IActivityEventListener([Of] ActivityExecutionStatusChangedEventArgs).OnEvent
                If (sender Is Nothing) Then
                    Throw New ArgumentNullException("sender")
                End If
                Dim executionContext As ActivityExecutionContext = [TryCast](sender,ActivityExecutionContext)
                If (executionContext Is Nothing) Then
                    Throw New ArgumentException(SR.Error_SenderMustBeActivityExecutionContext, "sender")
                End If
                DirectCast(executionContext.Activity, ReplicatorActivity).HandleStatusChange(executionContext, e, Me)
            End Sub


            ' Properties
            Friend ReadOnly Property RunIdentifier As Guid
                Get
                    Return Me.runId
                End Get
            End Property


            ' Fields
            Private runId As Guid
        End Class
    End Class
End Namespace

